package br.unisul.redeNeural;

/**
 * Classe para representa uma Rede Neural Artificial(RNA) chamada Regra Delta.<br>
 * Esta RNA é uma rede de unica camada, ou seja, possui apenas a camada de entra e a de saida.
 * @author Joelson
 *
 */
public class RegraDelta extends RedeNeural implements java.io.Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = -398139307380283901L;

	/**
	 * Constroi uma RNA Regra Delta, esta rede ignora as camadas intermediarias que possa possuir 
	 * na configuração.
	 * @param configuracao - configuração da RNA
	 */
	public RegraDelta(Configuracao configuracao) {
		super(configuracao);
	}

	public void treinar(ParTreino valoresTreino) throws RedeNeuralException {
		getConfiguracao().setMultiCamadas(false);
		inicializarValores();
		while(!verificarParada()){
			Neuronio n[] = getSaidas();
			for (int i = 0; i < valoresTreino.getQuantidade(); i++) {
				atualizarEntradas(valoresTreino.getEntrada(i));
				for (int j = 0; j < n.length; j++) {
					Peso [] pesosEntra = getPesosEntrada(1, j);
					Neuronio [] neuroniosEntradas = getNeuroniosEntrada(1, j);
					double saida = calcularSaidaNeuronio(neuroniosEntradas, pesosEntra, n[j]);
					saida = aplicarFuncaoAtivacao(saida);
					if(saida != valoresTreino.getSaida(i)[j]){
						for (int k = 0; k < pesosEntra.length; k++) {
							atualizarPeso(pesosEntra[k], (getConfiguracao().getTaxaAprendizado()*
									neuroniosEntradas[k].getValorNeuronio()*(valoresTreino.getSaida(i)[j] - saida)));
						}
						atualizarVies(n[j].getVies(), getConfiguracao().getTaxaAprendizado()*valoresTreino.getSaida(i)[j]);
					}
				}
			}
		}

	}

}
